package com.pokerpro.model;

import static com.pokerpro.Constant.Positions.*;
import static com.pokerpro.Constant.Colors.*;
import static com.pokerpro.support.Log.*;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.ArrayList;
import java.util.List;

import com.pokerpro.Scanner.ActionScanner;
import com.pokerpro.Scanner.BoardScanner;
import com.pokerpro.Scanner.HoleCardsScanner;
import com.pokerpro.enums.HandStrength;
import com.pokerpro.enums.StartingHandCategory;
import com.pokerpro.enums.StartingHandCategory.*;
import com.pokerpro.interfaces.TableEvents;
import com.pokerpro.support.BaseElement;

public class Table extends BaseElement implements Runnable, TableEvents {

	String test = "false";

	private int pointer;

	/*
	 * Global variables: no changes at all
	 */
	private int id;
	private TableEvents tableEvents;

	/*
	 * Variables per hand: changes with new holecards dealt
	 */
	private boolean seated = false;
	private HoleCards holeCards;
	private Card boardcard1;
	private Card boardcard2;
	private Card boardcard3;
	private Card boardcard4;
	private Card boardcard5;
	
	
	private int playerOnTable;
	private int dealerButton;

	/*
	 * Live information: updated neccessary during hand
	 */
	private boolean flop = false;
	private boolean turn = false;
	private boolean river = false;

	/*
	 * 
	 */
	private int otherPlayerOnTable;

	public Table(Robot pRobot, TableEvents pTableEvents, int pId) {
		super(pRobot);
		pointer = 0;
		tableEvents = pTableEvents;
		holeCards = new HoleCards();
		while (!isTableVisible()) {
			// wait until table is opened;
		}
		if (takeSeat()) {
			log("Table " + id + ": Seat taken!");
		} else {
			log("Table " + id + ": No Free seat available");
		}
	}

	public void run() {
		System.out.println("Table thread running");
		initThreads();

		while (true) {

		}
	}

	public void initThreads() {
		List<Point> list1 = new ArrayList<Point>();
		List<Point> list2 = new ArrayList<Point>();
		List<Point> list3 = new ArrayList<Point>();
		list1.add(TABLE1_OWN_CARD_LEFT);
		list1.add(TABLE1_OWN_CARD_RIGHT);
		list2.add(TABLE1_ACTION_BUTTON_LEFT);
		list2.add(TABLE1_ACTION_BUTTON_MIDDLE);
		list2.add(TABLE1_ACTION_BUTTON_RIGHT);
		list3.add(TABLE1_COMMUNITYCARD_1);
		list3.add(TABLE1_COMMUNITYCARD_2);
		list3.add(TABLE1_COMMUNITYCARD_3);
		list3.add(TABLE1_COMMUNITYCARD_4);
		list3.add(TABLE1_COMMUNITYCARD_5);

		Thread holeCardsScanner = new Thread(new HoleCardsScanner(getRobot(),
				list1, this));
		holeCardsScanner.start();
		Thread actionScanner = new Thread(new ActionScanner(getRobot(), list2,
				this));
		actionScanner.start();
		Thread boardScanner = new Thread(new BoardScanner(getRobot(), list3,
				this));
		boardScanner.start();
	}

	public boolean isTableVisible() {
		if (getPixelCol(TABLE1_BACKGROUND_POSITION).equals(COLOR_BACKGROUND))
			return true;
		else
			return false;
	}

	/**
	 * Try to take a seat. Iterating over all possible seats, checking for right
	 * popup color of a get Chips Dialogue
	 * 
	 * @return false if no free seat, else true
	 * @throws AWTException
	 */
	private boolean takeSeat() {

		boolean success = false;
		int tableNr = 1;
		while (!success && tableNr <= 9) {
			if (tableNr == 1) {
				mouseMoveAndClick(1, TABLE1_PLAYER1);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 2) {
				mouseMoveAndClick(1, TABLE1_PLAYER2);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 3) {
				mouseMoveAndClick(1, TABLE1_PLAYER3);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 4) {
				mouseMoveAndClick(1, TABLE1_PLAYER4);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 5) {
				mouseMoveAndClick(1, TABLE1_PLAYER5);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 6) {
				mouseMoveAndClick(1, TABLE1_PLAYER6);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 7) {
				mouseMoveAndClick(1, TABLE1_PLAYER7);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 8) {
				mouseMoveAndClick(1, TABLE1_PLAYER8);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			} else if (tableNr == 9) {
				mouseMoveAndClick(1, TABLE1_PLAYER9);
				if (isGetChipsDialogueVisible()) {
					success = true;
					mouseMoveAndClick(1, TABLE1_GET_CHIPS_DIALOGUE_OK_BUTTON);
					log("Table " + id + ": Money taken to table");
					break;
				}
			}
			tableNr++;
		}
		seated = success;
		return success;
	}

	private boolean isGetChipsDialogueVisible() {
		delay(1200);
		if (getPixelCol(TABLE1_GET_CHIPS_DIALOGUE).equals(
				COLOR_INDICATOR_GET_CHIPS_POPUP)) {
			return true;
		} else {
			return false;
		}
	}

	public boolean scanRectangleForColor(Rectangle e, Color color)
			throws AWTException {
		Robot robot = new Robot();
		int x = e.x;
		int y = e.y;
		Color c = new Color(0, 0, 0);
		boolean found = false;

		for (int i = (y + 18); i < (y + e.height) && found == false; i++) {
			int tempX = x;
			for (int j = x + 20; j < (x + e.width) && found == false; j++) {
				System.out.println("LOG: X: " + j + ";   Y: " + i);
				c = robot.getPixelColor(j, y);
				if (c.equals(color)) {
					found = true;
				}
			}
		}
		return found;
	}

	public void betAllIn() {
		mouseMove(TABLE1_SLIDER_TRIANGLE);
		getRobot().mousePress(InputEvent.BUTTON1_MASK);
		mouseMove(new Point(TABLE1_SLIDER_RIGHT.y, TABLE1_SLIDER_RIGHT.x + 50));
		getRobot().mouseRelease(InputEvent.BUTTON1_MASK);
		mouseMoveAndClick(1, TABLE1_ACTION_BUTTON_RIGHT);
	}

	public void fold() {
		mouseMoveAndClick(1, TABLE1_ACTION_BUTTON_LEFT);
	}

	public void check() {
		mouseMoveAndClick(1, TABLE1_ACTION_BUTTON_LEFT);
	}

	public void raise(int bbToRaise) {
		mouseMoveAndClick(bbToRaise, TABLE1_SLIDER_RIGHT);

	}

	/**
	 * scans hand and save Strings in global variable
	 */

	@Override
	public void seatingSuccessfull() {
		// TODO Auto-generated method stub

	}
	
	/**
	 * Calculate Hand Srength on Flop/Turn/River
	 */
	private HandStrength calculateHand() {
		HandStrength hand = HandStrength.HIGH_CARD;
		if (turn == false) {
			
		}
		
		else if (river = false) {
			
		}
		
		else if (river == true) {
			
		}
		
		return hand;
		
	}

	@Override
	public void newHoleCards(HoleCards pHoleCards) {
		flop = false;
		turn= false;
		river = false;
		holeCards = pHoleCards;
		System.out.println("NEW HAND -------");
		System.out.println(pHoleCards.getCardLeft().getCardString() + " ; "
				+ pHoleCards.getCardRight().getCardString());
		log("Hand Category: " + pHoleCards.getHandCategory());

	}

	@Override
	public void actionRequired() {
		if (holeCards.getHandCategory().equals(StartingHandCategory.PREMIUM)) {
			betAllIn();
		} else {
			check();
		}
	}

	@Override
	public void newFlop(List<Card> flopCards) {
		flop = true;
		boardcard1 = flopCards.get(0);
		boardcard2 = flopCards.get(0);
		boardcard3 = flopCards.get(0);
		log ("New Flop: ");
		log(flopCards.get(0).getCardString());
		log(flopCards.get(1).getCardString());
		log(flopCards.get(2).getCardString());

	}

	@Override
	public void newTurn(Card card) {
		log("New Turn: " + card.getCardString());
		turn = true;
		boardcard4 = card;
	}

	@Override
	public void newRiver(Card card) {
		log("New Turn: " + card.getCardString());
		river = true;
		boardcard5 = card;
	}

	@Override
	public void handFinished() {

	}

	@Override
	public void tableClosed() {
		
	}
}
